pub fn private_key(p: u64) -> u64 {
    (2..p).cycle().skip(5).next().unwrap()
    //todo!("Pick a private key greater than 1 and less than {p}")
}

pub fn public_key(p: u64, g: u64, a: u64) -> u64 {
    let g1 = g as u128;
    let mut tmp = g as u128;
    let mut cnt = a;
    while cnt > 0 {
        tmp *= g1;
        cnt -= 1;
    }
    let num = tmp % p as u128;
    println!("{}", num);
    num as u64
    //todo!("Calculate public key using prime numbers {p} and {g}, and private key {a}")
}

pub fn secret(p: u64, b_pub: u64, a: u64) -> u64 {
    b_pub.pow(a as u32) % p
    //todo!("Calculate secret key using prime number {p}, public key {b_pub}, and private key {a}")
}

#[test]
#[ignore]
fn public_key_correct_big_numbers() {
    let p: u64 = 4_294_967_299;
    let g: u64 = 8;
    let private_key: u64 = 4_294_967_296;
    let expected: u64 = 4096;
    assert_eq!(public_key(p, g, private_key), expected);
}

#[test]
#[ignore]
fn secret_key_correct_big_numbers() {
    let p: u64 = 4_294_967_927;
    let private_key_a = 4_294_967_300;
    let public_key_b = 843;
    let secret = secret(p, public_key_b, private_key_a);
    let expected = 1_389_354_282;
    assert_eq!(secret, expected);
}